home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / utility / uwserver.zip / uwserver.tar / server / uw_tty.c < prev    next >
C/C++ Source or Header  |  1991-01-25  |  9KB  |  351 lines

  1. /*
  2.  *    uw_tty - terminal support for UW
  3.  *
  4.  * Copyright 1985,1986 by John D. Bruner.  All rights reserved.  Permission to
  5.  * copy this program is given provided that the copy is not sold and that
  6.  * this copyright notice is included.
  7.  */
  8.  
  9. #include <sys/types.h>
  10. #include <sys/file.h>
  11. #include <sys/ioctl.h>
  12. #include <sys/stat.h>
  13.  
  14. #include "uw_param.h"
  15. #include "uw_win.h"
  16. #include "uw_opt.h"
  17.  
  18. #define    XON    021    /* ASCII XON (ASR-33 paper-tape reader on) */
  19. #define    XOFF    023    /* ASCII XOFF (ASR-33 paper-tape reader off) */
  20.  
  21. static char *envinfo[][3] = {
  22.     {
  23.         "TERM=adm31",
  24.         "TERMCAP=adm31:cr=^M:do=^J:nl=^J:al=\\EE:am:le=^H:bs:ce=\\ET:cm=\\E=%+ %+ :cl=^Z:cd=\\EY:co#80:dc=\\EW:dl=\\ER:ei=\\Er:ho=^^:im=\\Eq:li#24:mi:nd=^L:up=^K:MT:km:so=\\EG1:se=\\EG0:",
  25.         (char *)0
  26.     },
  27.     {
  28.         "TERM=vt52",
  29.         (char *)0
  30.     },
  31.     {
  32.         "TERM=ansi",
  33.         (char *)0
  34.     },
  35.     {
  36.         "TERM=tek4010",
  37.         (char *)0
  38.     }
  39. };
  40.  
  41. /* private (emulation-specific) data */
  42. struct tty {
  43.     struct {
  44.         unsigned short    h,v;
  45.     }        t_size;
  46.     unsigned    t_fontsz;
  47.     unsigned    t_clipb;
  48.     unsigned    t_bell;
  49.     unsigned    t_curs;
  50.     unsigned    t_chgsz;
  51. };
  52.  
  53. #define    WOTTY_SIZE    8        /* terminal size in (row, col) */
  54. #define    WOTTY_FONTSZ    9        /* font size index (0=7pt, 1=9pt) */
  55. #define    WOTTY_CLIPB    10        /* 0=clipboard, 1=encode mouse clicks */
  56. #define    WOTTY_BELL    11        /* bell: bit 0=visible, bit 1=audible */
  57. #define    WOTTY_CURSOR    12        /* cursor type: 0=block, 1=underscore */
  58. #define    WOTTY_CHGSZ    13        /* change actual size (not view size) */
  59.  
  60. static woptarg_t size_xdr[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END };
  61. static woptarg_t fontsz_xdr[] = { WOA_UDATA(6), WOA_END };
  62. static woptarg_t clipb_xdr[] = { WOA_UDATA(1), WOA_END };
  63. static woptarg_t bell_xdr[] = { WOA_UDATA(2), WOA_END };
  64. static woptarg_t curs_xdr[] = { WOA_UDATA(1), WOA_END };
  65. static woptarg_t chgsz_xdr[] = { WOA_UDATA(1), WOA_END };
  66.  
  67. /* TIOCSWINSZ is in 4.3BSD, TIOCSSIZE is in Sun UNIX */
  68. #if defined(TIOCSWINSZ) || defined(TIOCSSIZE)
  69. #define    RPTWINSZ    (1<<WOTTY_SIZE)
  70. #else
  71. #define    RPTWINSZ    0
  72. #endif
  73.  
  74. #define    TTY_WOPT    {                    \
  75.     0, 0, 0, 0,                        \
  76.     RPTWINSZ|(1<<WOTTY_FONTSZ)|(1<<WOTTY_CLIPB)|        \
  77.      (1<<WOTTY_BELL)|(1<<WOTTY_CURSOR)|(1<<WOTTY_CHGSZ),    \
  78.     {                            \
  79.         { NULL, NULL, NULL },                \
  80.         { NULL, NULL, NULL },                \
  81.         { NULL, NULL, NULL },                \
  82.         { NULL, NULL, NULL },                \
  83.         { NULL, NULL, NULL },                \
  84.         { NULL, NULL, NULL },                \
  85.         { NULL, NULL, NULL },                \
  86.         { NULL, NULL, NULL },                \
  87.         { size_xdr, tty_getopt, tty_setopt },        \
  88.         { fontsz_xdr, tty_getopt, tty_setopt },        \
  89.         { clipb_xdr, tty_getopt, tty_setopt },        \
  90.         { bell_xdr, tty_getopt, tty_setopt },        \
  91.         { curs_xdr, tty_getopt, tty_setopt },        \
  92.         { chgsz_xdr, tty_getopt, tty_setopt }        \
  93.     }                            \
  94. }
  95. extern int tty_start();
  96. extern void tty_stop(), tty_setopt(), tty_setext();
  97. extern char *tty_getopt();
  98.  
  99. struct emulation adm31_emul = { TTY_WOPT, tty_start, tty_stop, tty_setext };
  100. struct emulation vt52_emul = { TTY_WOPT, tty_start, tty_stop, tty_setext };
  101. struct emulation ansi_emul = { TTY_WOPT, tty_start, tty_stop, tty_setext };
  102. struct emulation tek_emul = { { 0, 0, 0, 0, 0 }, tty_start, tty_stop };
  103.  
  104. tty_mode(f)
  105. int f;
  106. {
  107.     static struct sgttyb ostty, nstty;
  108.     static struct tchars otchars, ntchars;
  109.     static struct ltchars oltchars, nltchars;
  110.     static int olmode, nlmode;
  111.     static int operm;
  112.     static saved;
  113.     static int inout = FREAD|FWRITE;
  114.     struct stat st;
  115.  
  116.     /*
  117.      * This routine either saves the current terminal modes and then
  118.      * sets up the terminal line or resets the terminal modes (depending
  119.      * upon the value of "f").  The terminal line is used in "cbreak"
  120.      * mode with all special characters except XON/XOFF disabled.  The
  121.      * hated (by me) LDECCTQ mode is required for the Macintosh to
  122.      * handle flow control properly.
  123.      */
  124.     if (f == 1) {
  125.         if (fstat(0, &st) == 0)
  126.             operm = st.st_mode & 06777;
  127.         else
  128.             operm = -1;
  129.         if (ioctl(0, (int)TIOCGETP, (char *)&ostty) < 0) {
  130.             perror("ioctl((int)TIOCGETP)");
  131.             done(1);
  132.         }
  133.         if (ioctl(0, (int)TIOCGETC, (char *)&otchars) < 0) {
  134.             perror("ioctl((int)TIOCGETC)");
  135.             done(1);
  136.         }
  137.         if (ioctl(0, (int)TIOCGLTC, (char *)&oltchars) < 0) {
  138.             perror("ioctl((int)TIOCGLTC)");
  139.             done(1);
  140.         }
  141.         if (ioctl(0, (int)TIOCLGET, (char *)&olmode) < 0) {
  142.             perror("ioctl((int)TIOCLGET)");
  143.             done(1);
  144.         }
  145.         nstty = ostty;
  146.         nstty.sg_erase = nstty.sg_kill = -1;
  147.         nstty.sg_flags |= CBREAK;
  148.         nstty.sg_flags &= ~(RAW|CRMOD|ECHO|LCASE|XTABS|ALLDELAY);
  149.         ntchars.t_intrc = ntchars.t_quitc = -1;
  150.         ntchars.t_eofc = ntchars.t_brkc = -1;
  151.         ntchars.t_startc = XON;
  152.         ntchars.t_stopc = XOFF;
  153.         nltchars.t_suspc = nltchars.t_dsuspc = -1;
  154.         nltchars.t_rprntc = nltchars.t_flushc = -1;
  155.         nltchars.t_werasc = nltchars.t_lnextc = -1;
  156.         nlmode = olmode | LDECCTQ;
  157.         if (operm != -1 && fchmod(0, S_IREAD|S_IWRITE) < 0)
  158.             operm = -1;
  159.         if (ioctl(0, (int)TIOCSETN, (char *)&nstty) < 0) {
  160.             perror("ioctl((int)TIOCSETN)");
  161.             done(1);
  162.         }
  163.         if (ioctl(0, (int)TIOCSETC, (char *)&ntchars) < 0) {
  164.             perror("ioctl((int)TIOCSETC");
  165.             done(1);
  166.         }
  167.         if (ioctl(0, (int)TIOCSLTC, (char *)&nltchars) < 0) {
  168.             perror("ioctl((int)TIOCSLTC");
  169.             done(1);
  170.         }
  171.         if (ioctl(0, (int)TIOCLSET, (char *)&nlmode) < 0) {
  172.             perror("ioctl((int)TIOCLSET)");
  173.             done(1);
  174.         }
  175.         saved = 1;
  176.     } else if (saved) {
  177.         (void)ioctl(0, (int)TIOCFLUSH, (char *)&inout);
  178.         (void)ioctl(0, (int)TIOCSETP, (char *)&ostty);
  179.         (void)ioctl(0, (int)TIOCSETC, (char *)&otchars);
  180.         (void)ioctl(0, (int)TIOCSLTC, (char *)&oltchars);
  181.         (void)ioctl(0, (int)TIOCLSET, (char *)&olmode);
  182.         if (operm != -1)
  183.             (void)fchmod(0, operm);
  184.     }
  185. }
  186.  
  187. static
  188. tty_start(w)
  189. register struct window *w;
  190. {
  191.     register struct tty *t;
  192.     extern char *malloc();
  193.  
  194.     /*
  195.      * Start up a terminal emulation.  Establish reasonable defaults
  196.      * for the terminal-specific window options.
  197.      */
  198.     if (w->w_type != WT_TEK4010) {
  199.         if ((w->w_private = malloc(sizeof(struct tty))) != NULL) {
  200.             t = (struct tty *)w->w_private;
  201.             t->t_size.h = 80;
  202.             t->t_size.v = 24;
  203.             t->t_fontsz = 0;
  204.             t->t_clipb = 0;
  205.             t->t_bell = 3;
  206.             t->t_curs = 0;
  207.             t->t_chgsz = 0;
  208.             return(1);
  209.         } else
  210.             return(0);
  211.     } else {
  212.         w->w_private = (char *)0;
  213.         return(1);
  214.     }
  215. }
  216.  
  217. static
  218. void
  219. tty_stop(w)
  220. register struct window *w;
  221. {
  222.     /*
  223.      * Shut down (stop) a terminal emulation.
  224.      */
  225.     free(w->w_private);
  226.     w->w_private = (char *)0;
  227. }
  228.  
  229. static
  230. void
  231. tty_setext(wod)
  232. register struct woptdefn *wod;
  233. {
  234.     /*
  235.      * This routine makes adjustments to the window option definitions
  236.      * for external windows.  Basically, we turn off reporting for
  237.      * WOTTY_SIZE.  (If the external process wants to handle this, it
  238.      * can turn it back on.)
  239.      */
  240.     WOPT_CLR(wod->wod_do, WOTTY_SIZE);
  241.     WOPT_CLR(wod->wod_askrpt, WOTTY_SIZE);
  242. }
  243.  
  244. tty_envinit(wtype)
  245. register wtype_t wtype;
  246. {
  247.     /*
  248.      * Set up environment variables corresponding to the window type
  249.      * "wtype".
  250.      */
  251.     env_set(envinfo[wtype]);
  252. }
  253.  
  254. static
  255. char *
  256. tty_getopt(win, num)
  257. caddr_t win;
  258. woption_t num;
  259. {
  260.     register struct tty *t;
  261.     static union optvalue ov;
  262.     struct window *w;
  263.  
  264.     if ((w=(struct window *)win) != NULL && w->w_alloc &&
  265.         (t=(struct tty *)w->w_private) != NULL) {
  266.         switch (num) {
  267.         case WOTTY_SIZE:
  268.             ov.ov_point.h = t->t_size.h;
  269.             ov.ov_point.v = t->t_size.v;
  270.             break;
  271.         case WOTTY_FONTSZ:
  272.             ov.ov_udata6 = t->t_fontsz;
  273.             break;
  274.         case WOTTY_CLIPB:
  275.             ov.ov_udata1 = t->t_clipb;
  276.             break;
  277.         case WOTTY_BELL:
  278.             ov.ov_udata2 = t->t_bell;
  279.             break;
  280.         case WOTTY_CURSOR:
  281.             ov.ov_udata1 = t->t_curs;
  282.             break;
  283.         case WOTTY_CHGSZ:
  284.             ov.ov_udata1 = t->t_chgsz;
  285.             break;
  286.         }
  287.     }
  288.     return((char *)&ov);
  289. }
  290.  
  291. static
  292. void
  293. tty_setopt(win, num, value)
  294. caddr_t win;
  295. woption_t num;
  296. char *value;
  297. {
  298.     register struct tty *t;
  299.     register union optvalue *ovp;
  300.     register struct window *w;
  301.  
  302.     if ((w=(struct window *)win) != NULL && w->w_alloc &&
  303.         (t=(struct tty *)w->w_private) != NULL &&
  304.         (ovp = (union optvalue *)value) != NULL) {
  305.         switch (num) {
  306.         case WOTTY_SIZE:
  307.             t->t_size.h = ovp->ov_point.h;
  308.             t->t_size.v = ovp->ov_point.v;
  309. #ifdef TIOCSWINSZ
  310.             if (w->w_class == WC_INTERNAL) {
  311.                 /* set window size on pty (4.3BSD) */
  312.                 struct winsize ws;
  313.                 ws.ws_row = t->t_size.v;
  314.                 ws.ws_col = t->t_size.h;
  315.                 ws.ws_xpixel = w->w_size.h;
  316.                 ws.ws_ypixel = w->w_size.v;
  317.                 (void)ioctl(w->w_datafd, (int)TIOCSWINSZ,
  318.                     (char *)&ws);
  319.             }
  320. #else
  321. #ifdef TIOCSSIZE
  322.             if (w->w_class == WC_INTERNAL) {
  323.                 /* set window size on pty (Sun) */
  324.                 struct ttysize ts;
  325.                 ts.ts_lines = t->t_size.v;
  326.                 ts.ts_cols = t->t_size.h;
  327.                 (void)ioctl(w->w_datafd, (int)TIOCSSIZE,
  328.                     (char *)&ts);
  329.             }
  330. #endif
  331. #endif
  332.             break;
  333.         case WOTTY_FONTSZ:
  334.             t->t_fontsz = ovp->ov_udata6;
  335.             break;
  336.         case WOTTY_CLIPB:
  337.             t->t_clipb = ovp->ov_udata1;
  338.             break;
  339.         case WOTTY_BELL:
  340.             t->t_bell = ovp->ov_udata2;
  341.             break;
  342.         case WOTTY_CURSOR:
  343.             t->t_curs = ovp->ov_udata1;
  344.             break;
  345.         case WOTTY_CHGSZ:
  346.             t->t_chgsz = ovp->ov_udata1;
  347.             break;
  348.         }
  349.     }
  350. }
  351.